home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / config / dsp16xx / dsp16xx.md < prev    next >
Text File  |  1994-11-07  |  57KB  |  2,181 lines

  1. ;;- Machine description for the AT&T DSP1600 for GNU C compiler
  2. ;;  Copyright (C) 1994 Free Software Foundation, Inc.
  3. ;;  Contributed by Michael Collison (collison@world.std.com).
  4.  
  5. ;; This file is part of GNU CC.
  6.  
  7. ;; GNU CC is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation; either version 2, or (at your option)
  10. ;; any later version.
  11.  
  12. ;; GNU CC is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;; GNU General Public License for more details.
  16.  
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU CC; see the file COPYING.  If not, write to
  19. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  
  22. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  23.  
  24. ;; Attribute specifications
  25.  
  26. ; Type of each instruction.  Default is arithmetic.
  27. ; I'd like to write the list as this, but genattrtab won't accept it.
  28. ;
  29. ; "jump,cond_jump,call,            ; flow-control instructions
  30. ;  load_i,load, store, move        ; Y space address arithmetic instructions
  31. ;  malu,special,f3_alu,f3_alu_i        ; data arithmetic unit instructions
  32. ;  shift_i,shift, bfield_i, bfield    ; bit manipulation unit instructions
  33. ;  arith,                ; integer unit instructions
  34. ;  nop
  35.  
  36. ; Classification of each insn.  Some insns of TYPE_BRANCH are multi-word.
  37. (define_attr "type"
  38.   "jump,cond_jump,call,load_i,load,move,store,malu,malu_mul,special,f3_alu,f3_alu_i,shift_i,shift,bfield_i,bfield,nop,ld_short_i"
  39.   (const_string "malu"))
  40.  
  41. ; Length in # of instructions of each insn.  The values are not exact, but
  42. ; are safe.
  43. (define_attr "length" ""
  44.   (cond [(eq_attr "type" "cond_jump,f3_alu_i,shift_i,bfield_i,load_i")
  45.      (const_int 2)]
  46.     (const_int 1)))
  47.  
  48.  
  49. ;;  ....................
  50. ;;
  51. ;;  Test against 0 instructions
  52. ;;
  53. ;;  ....................
  54.  
  55. (define_expand "tsthi"
  56.   [(set (cc0)
  57.         (match_operand:HI 0 "register_operand" ""))]
  58.   ""
  59.   "
  60. {
  61.   dsp16xx_compare_gen = gen_tst_reg;
  62.   dsp16xx_compare_op0 = operands[0];
  63.   dsp16xx_compare_op1 = const0_rtx;
  64.   DONE;
  65. }")
  66.  
  67. (define_insn "tsthi_1"
  68.   [(set (cc0)
  69.     (match_operand:HI 0 "register_operand" "A"))]
  70.   ""
  71.   "%0=%0"
  72.   [(set_attr "type" "malu")])
  73.  
  74. (define_expand "tstqi"
  75.   [(set (cc0)
  76.         (match_operand:QI 0 "register_operand" ""))]
  77.   ""
  78.   "
  79. {
  80.   dsp16xx_compare_gen = gen_tst_reg;
  81.   dsp16xx_compare_op0 = operands[0];
  82.   dsp16xx_compare_op1 = const0_rtx;
  83.   DONE;
  84. }")
  85.  
  86. (define_insn "tstqi_1"
  87.   [(set (cc0)
  88.     (match_operand:QI 0 "register_operand" "j,q"))
  89.    (clobber (match_scratch:QI 1 "=k,u"))]
  90.   ""
  91.   "@
  92.    %1=0\;%b0-0
  93.    %1=0\;%b0-0"
  94.   [(set_attr "type" "malu,malu")])
  95.  
  96.  
  97. ;;
  98. ;;  ....................
  99. ;;
  100. ;;  Bit test instructions
  101. ;;
  102. ;;  ....................
  103.  
  104. (define_insn ""
  105.   [(set (cc0)
  106.     (and:HI (match_operand:HI 0 "register_operand" "A,!A,A")
  107.         (match_operand:HI 1 "nonmemory_operand" "Z,A,I")))]
  108.   "" 
  109.   "*
  110. {
  111.     switch (which_alternative)
  112.     {
  113.        case 0:
  114.        case 1:
  115.              return \"%0&%1\";
  116.  
  117.        case 2:
  118.              return \"%0&%H1\";
  119.          }
  120. }"
  121.   [(set_attr "type" "f3_alu,malu,f3_alu_i")])
  122.  
  123.  
  124. ;;(define_insn ""
  125. ;;  [(set (cc0)
  126. ;;    (and:QI (match_operand:QI 0 "register_operand" "h")
  127. ;;        (match_operand:QI 1 "const_int_operand" "I")))]
  128. ;;  "" 
  129. ;;  "%b0&%H1"
  130. ;;  [(set_attr "type" "f3_alu_i")])
  131.  
  132. ;;
  133. ;;
  134. ;; Compare Instructions
  135. ;;
  136.  
  137. (define_expand "cmphi"
  138.   [(parallel [(set (cc0)
  139.            (compare (match_operand:HI 0 "general_operand" "")
  140.                 (match_operand:HI 1 "general_operand" "")))
  141.           (clobber (match_scratch:QI 2 ""))
  142.           (clobber (match_scratch:QI 3 ""))
  143.           (clobber (match_scratch:QI 4 ""))
  144.           (clobber (match_scratch:QI 5 ""))])]
  145.   ""
  146.   "
  147. {
  148.   if (GET_CODE (operands[1]) == CONST_INT)
  149.     operands[1] = force_reg (HImode, operands[1]);
  150.  
  151.   if (operands[0])    /* Avoid unused code warning */
  152.     {
  153.       dsp16xx_compare_gen = gen_compare_reg;
  154.       dsp16xx_compare_op0 = operands[0];
  155.       dsp16xx_compare_op1 = operands[1];
  156.       DONE;
  157.     }
  158.  
  159. }")
  160.  
  161. (define_insn ""
  162.   [(set (cc0) 
  163.     (compare (match_operand:HI 0 "general_operand" "Z*r*m*i")
  164.          (match_operand:HI 1 "general_operand" "Z*r*m*i")))
  165.    (clobber (match_scratch:QI 2 "=&A"))
  166.    (clobber (match_scratch:QI 3 "=&A"))
  167.    (clobber (match_scratch:QI 4 "=&A"))
  168.    (clobber (match_scratch:QI 5 "=&A"))]
  169.   "(save_next_cc_user_code = next_cc_user_code (insn)) == GTU \
  170.    || save_next_cc_user_code == GEU \
  171.    || save_next_cc_user_code == LTU \
  172.    || save_next_cc_user_code == LEU"
  173.   "*
  174. {
  175.   if (GET_CODE(operands[0]) == REG)
  176.     {
  177.       if (REGNO (operands[0]) == REG_Y ||
  178.       REGNO (operands[0]) == REG_PROD)
  179.     {
  180.       output_asm_insn (\"a0=%0\", operands);
  181.     }
  182.       else if (IS_YBASE_REGISTER_WINDOW (REGNO(operands[0])))
  183.     {
  184.       output_asm_insn (\"a0=%u0\;a0l=%w0\", operands);
  185.     }
  186.       else
  187.     fatal (\"Illegal register for compare\");
  188.     }
  189.   else if (GET_CODE(operands[0]) == CONST_INT)
  190.     {
  191.       output_asm_insn (\"a0=%U0\;a0l=%H0\", operands);
  192.     }
  193.   else if (GET_CODE (operands[0]) == MEM)
  194.     {
  195.       rtx xoperands[2];
  196.  
  197.       xoperands[0] = gen_rtx (REG, HImode, REG_A0);
  198.       xoperands[1] = operands[0];
  199.       double_reg_from_memory (xoperands);
  200.     }
  201.  
  202.   if (GET_CODE(operands[1]) == REG)
  203.     {
  204.       if (REGNO (operands[1]) == REG_Y ||
  205.       REGNO (operands[1]) == REG_PROD)
  206.     {
  207.       output_asm_insn (\"a1=%1\", operands);
  208.     }
  209.       else if (IS_YBASE_REGISTER_WINDOW (REGNO(operands[1])))
  210.     {
  211.       output_asm_insn (\"a1=%u1\;a1l=%w1\", operands);
  212.     }
  213.       else
  214.     fatal (\"Illegal register for compare\");
  215.     }
  216.   else if (GET_CODE (operands[1]) == MEM)
  217.     {
  218.       rtx xoperands[2];
  219.  
  220.       xoperands[0] = gen_rtx (REG, HImode, REG_A1);
  221.       xoperands[1] = operands[1];
  222.       double_reg_from_memory (xoperands);
  223.     }
  224.   else if (GET_CODE(operands[1]) == CONST_INT)
  225.     {
  226.       output_asm_insn (\"a1=%U1\;a1l=%H1\", operands);
  227.     }
  228.   
  229.   return \"psw = 0\;a0 - a1\";
  230. }")
  231.  
  232. (define_insn ""
  233.   [(set (cc0) (compare (match_operand:HI 0 "register_operand" "A,!A")
  234.                (match_operand:HI 1 "register_operand" "Z,*A")))]
  235.   ""
  236.   "@
  237.    %0-%1
  238.    %0-%1"
  239.   [(set_attr "type" "malu,f3_alu")])
  240.  
  241. (define_expand "cmpqi"
  242.   [(parallel [(set (cc0)
  243.            (compare (match_operand:QI 0 "register_operand" "")
  244.                 (match_operand:QI 1 "nonmemory_operand" "")))
  245.           (clobber (match_operand:QI 2 "register_operand" ""))
  246.           (clobber (match_operand:QI 3 "register_operand" ""))])]
  247.   ""
  248.   "
  249.  {
  250.   if (operands[0])    /* Avoid unused code warning */
  251.     {
  252.       dsp16xx_compare_gen = gen_compare_reg;
  253.       dsp16xx_compare_op0 = operands[0];
  254.       dsp16xx_compare_op1 = operands[1];
  255.       DONE;
  256.     }
  257.  }")
  258.  
  259. (define_insn ""
  260.   [(set (cc0) (compare (match_operand:QI 0 "register_operand"  "k,k,!k,k,u,u,!u,u")
  261.                        (match_operand:QI 1 "nonmemory_operand" "w,z,u,i,w,z,k,i")))
  262.     (clobber (match_scratch:QI 2 "=j,j,j,j,q,q,q,q"))
  263.     (clobber (match_scratch:QI 3 "=v,y,q,X,v,y,j,X"))]
  264.   "(save_next_cc_user_code = next_cc_user_code (insn)) == GTU \
  265.    || save_next_cc_user_code == GEU \
  266.    || save_next_cc_user_code == LTU \
  267.    || save_next_cc_user_code == LEU"
  268.   "@
  269.    %2=0\;%3=0\;%2-%3
  270.    %2=0\;%3=0\;%2-%3
  271.    %2=0\;%3=0\;%2-%3
  272.    %2=0\;%0-%H1
  273.    %2=0\;%3=0\;%2-%3
  274.    %2=0\;%3=0\;%2-%3
  275.    %2=0\;%3=0\;%2-%3
  276.    %2=0\;%0-%H1")
  277.  
  278.  
  279. (define_insn ""
  280.   [(set (cc0) (compare (match_operand:QI 0 "register_operand"  "j,j,!j,j,q,q,!q,q")
  281.                        (match_operand:QI 1 "nonmemory_operand" "v,y,q,i,v,y,j,i")))
  282.     (clobber (match_scratch:QI 2 "=k,k,k,k,u,u,u,u"))
  283.     (clobber (match_scratch:QI 3 "=w,z,u,X,w,z,k,X"))]
  284.   ""
  285.   "@
  286.    %2=0\;%3=0\;%0-%1
  287.    %2=0\;%3=0\;%0-%1
  288.    %2=0\;%3=0\;%0-%1
  289.    %2=0\;%b0-%H1
  290.    %2=0\;%3=0\;%0-%1
  291.    %2=0\;%3=0\;%0-%1
  292.    %2=0\;%3=0\;%0-%1
  293.    %2=0\;%b0-%H1")
  294.  
  295.  
  296. (define_expand "cmphf"
  297.   [(set (cc0)
  298.     (compare (match_operand:HF 0 "register_operand" "")
  299.          (match_operand:HF 1 "nonmemory_operand" "")))]
  300.   ""
  301.   "
  302. {
  303.   if (!dsp16xx_cmphf3_libcall)
  304.     dsp16xx_cmphf3_libcall = gen_rtx (SYMBOL_REF, Pmode, CMPHF3_LIBCALL);
  305.  
  306.    dsp16xx_compare_gen = gen_compare_reg;
  307.    dsp16xx_compare_op0 = operands[0];
  308.    dsp16xx_compare_op1 = operands[1];
  309.    emit_library_call (dsp16xx_cmphf3_libcall, 1, HImode, 2,
  310.               operands[0], HFmode,
  311.               operands[1], HFmode);
  312.    emit_insn (gen_tsthi_1 (copy_to_reg(hard_libcall_value (HImode))));
  313.    DONE;
  314. }")
  315.  
  316.  
  317. ;;  ....................
  318. ;;
  319. ;;  Add instructions
  320. ;;
  321. ;;  ....................
  322.  
  323.  
  324. (define_insn "addhi3"
  325.   [(set (match_operand:HI 0 "register_operand" "=A,A,A")
  326.     (plus:HI (match_operand:HI 1 "register_operand" "%A,A,A")
  327.          (match_operand:HI 2 "nonmemory_operand" "Z,d,i")))]
  328.   ""
  329.   "@
  330.    %0=%1+%2
  331.    %0=%1+%2
  332.    %0=%w1+%H2\;%0=%b0+%U2"
  333.   [(set_attr "type" "malu,malu,f3_alu_i")])
  334.  
  335. (define_insn ""
  336.   [(set (match_operand:QI 0 "register_operand" "=k,u,!k,!u")
  337.     (plus:QI (plus:QI (match_operand:QI 1 "register_operand" "uk,uk,uk,uk")
  338.               (match_operand:QI 2 "register_operand" "wz,wz,uk,uk"))
  339.          (match_operand:QI 3 "immediate_operand" "i,i,i,i")))
  340.    (clobber (match_scratch:QI 4 "=j,q,j,q"))]
  341.   ""
  342.   "@
  343.    %m0=%m1+%m2\;%m0=%0+%H3
  344.    %m0=%m1+%m2\;%m0=%0+%H3
  345.    %m0=%m1+%m2\;%m0=%0+%H3
  346.    %m0=%m1+%m2\;%m0=%0+%H3")
  347.  
  348. (define_expand "addqi3"
  349.   [(parallel [(set (match_operand:QI 0 "register_operand" "")
  350.            (plus:QI (match_operand:QI 1 "register_operand" "")
  351.                 (match_operand:QI 2 "nonmemory_operand" "")))
  352.           (clobber (match_scratch:QI 3 ""))])]
  353.   ""
  354.   "
  355. {
  356.   if (reload_in_progress)
  357.     {
  358.       if (REG_P (operands[1]) && 
  359.       (REGNO(operands[1]) == STACK_POINTER_REGNUM ||
  360.        REGNO(operands[1]) == FRAME_POINTER_REGNUM) &&
  361.       GET_CODE (operands[2]) == CONST_INT)
  362.     {
  363.       if (REG_P (operands[0]) && IS_ACCUM_REG(REGNO(operands[0])))
  364.         emit_move_insn (operands[0], operands[1]);
  365.  
  366.       operands[1] = operands[0];
  367.     }
  368.     }
  369. }")
  370.  
  371.     
  372. (define_insn "match_addqi3"
  373.   [(set (match_operand:QI 0 "register_operand" "=!a,!a,k,u,!k,!u,h,!a")
  374.     (plus:QI (match_operand:QI 1 "register_operand" "0,0,uk,uk,uk,uk,h,0")
  375.          (match_operand:QI 2 "nonmemory_operand" "W,N,wzi,wzi,uk,uk,i,n")))
  376.     (clobber (match_scratch:QI 3 "=X,X,j,q,j,q,X,W"))]
  377.   ""
  378.   "*
  379. {
  380.   switch (which_alternative)
  381.     {
  382.     case 0:
  383.       return \"*%0++%2\";
  384.  
  385.     case 1:
  386.       switch (INTVAL (operands[2]))
  387.     {
  388.     case -1:
  389.       return \"*%0--\";
  390.  
  391.     case 1:
  392.       return \"*%0++\";
  393.  
  394.     case -2:
  395.       return \"*%0--\;*%0--\";
  396.  
  397.     case 2:
  398.       return \"*%0++\;*%0++\";
  399.     }
  400.  
  401.     case 2:
  402.     case 3:
  403.       if (!CONSTANT_P(operands[2]))
  404.         return \"%m0=%m1+%m2\";
  405.       else
  406.         return \"%m0=%1+%H2\";
  407.  
  408.     case 4:
  409.     case 5:
  410.       return \"%m0=%m1+%m2\";
  411.  
  412.     case 6:
  413.       return \"%0=%b1+%H2\";
  414.  
  415.     case 7:
  416.       return \"%3=%2\;*%0++%3\";
  417.     }
  418. }")
  419.  
  420. (define_expand "addhf3"
  421.   [(set (match_operand:HF 0 "register_operand" "")
  422.     (plus:HF (match_operand:HF 1 "register_operand" "")
  423.          (match_operand:HF 2 "nonmemory_operand" "")))]
  424.   ""
  425.   "
  426. {
  427.   if (!dsp16xx_addhf3_libcall)
  428.     dsp16xx_addhf3_libcall = gen_rtx (SYMBOL_REF, Pmode, ADDHF3_LIBCALL);
  429.  
  430.    emit_library_call (dsp16xx_addhf3_libcall, 1, HFmode, 2,
  431.               operands[1], HFmode,
  432.               operands[2], HFmode);
  433.    emit_move_insn (operands[0], hard_libcall_value(HFmode));
  434.    DONE;
  435. }")
  436.               
  437.  
  438. ;;
  439. ;;  ....................
  440. ;;
  441. ;;  Subtract instructions
  442. ;;
  443. ;;  ....................
  444.  
  445. (define_insn "subhi3"
  446.   [(set (match_operand:HI 0 "register_operand" "=A,A,A")
  447.     (minus:HI (match_operand:HI 1 "register_operand" "A,A,A")
  448.           (match_operand:HI 2 "nonmemory_operand" "Z,d,i")))]
  449.   ""
  450.   "@
  451.    %0=%1-%2
  452.    %0=%1-%2
  453.    %0=%w1-%H2\;%0=%b0-%U2"
  454.   [(set_attr "type" "malu,malu,f3_alu_i")])
  455.  
  456. (define_insn "subqi3"
  457.   [(set (match_operand:QI 0 "register_operand" "=?*a,k,u,!k,!u")
  458.     (minus:QI (match_operand:QI 1 "register_operand" "0,uk,uk,uk,uk")
  459.          (match_operand:QI 2 "nonmemory_operand" "n,wzi,wzi,uk,uk")))
  460.     (clobber (match_scratch:QI 3 "=W,j,q,j,q"))]
  461.   ""
  462.   "*
  463. {
  464.   switch (which_alternative)
  465.     {
  466.     case 0:
  467.       switch (INTVAL (operands[2]))
  468.     {
  469.     case 0:
  470.       return \"\";
  471.       
  472.     case 1:
  473.       return \"*%0--\";
  474.       
  475.     case -1:
  476.       return \"*%0++\";
  477.       
  478.     default:
  479.       operands[2] = GEN_INT (-INTVAL (operands[2]));
  480.       
  481.       if (SHORT_IMMEDIATE(operands[2]))
  482.         return \"set %3=%H2\;*%0++%3\";
  483.       else
  484.         return \"%3=%H2\;*%0++%3\";
  485.     }
  486.       
  487.     case 1:
  488.     case 2:
  489.       if (!CONSTANT_P(operands[2]))
  490.         return \"%m0=%m1-%m2\";
  491.       else
  492.         return \"%m0=%1-%H2\";
  493.  
  494.     case 3:
  495.     case 4:
  496.       return \"%m0=%m1-%m2\";
  497.     }
  498. }")
  499.  
  500. (define_expand "subhf3"
  501.   [(set (match_operand:HF 0 "register_operand" "")
  502.     (minus:HF (match_operand:HF 1 "register_operand" "")
  503.          (match_operand:HF 2 "nonmemory_operand" "")))]
  504.   ""
  505.   "
  506. {
  507.   if (!dsp16xx_subhf3_libcall)
  508.     dsp16xx_subhf3_libcall = gen_rtx (SYMBOL_REF, Pmode, SUBHF3_LIBCALL);
  509.   
  510.   emit_library_call (dsp16xx_subhf3_libcall, 1, HFmode, 2,
  511.              operands[1], HFmode,
  512.              operands[2], HFmode);
  513.   emit_move_insn (operands[0], hard_libcall_value(HFmode));
  514.   DONE;
  515. }")
  516.  
  517. (define_insn "neghi2"
  518.   [(set (match_operand:HI 0 "register_operand" "=A")
  519.         (neg:HI (match_operand:HI 1 "register_operand" "A")))]
  520.   ""
  521.   "%0=-%1"
  522.   [(set_attr "type" "special")])
  523.  
  524. (define_expand "neghf2"
  525.   [(set (match_operand:HF 0 "general_operand" "")
  526.     (neg:HF (match_operand:HF 1 "general_operand" "")))]
  527.   ""
  528. "
  529. {
  530.   if (!dsp16xx_neghf2_libcall)
  531.     dsp16xx_neghf2_libcall = gen_rtx (SYMBOL_REF, Pmode, NEGHF2_LIBCALL);
  532.   
  533.   emit_library_call (dsp16xx_neghf2_libcall, 1, HFmode, 1,
  534.              operands[1], HFmode);
  535.   emit_move_insn (operands[0], hard_libcall_value(HFmode));
  536.   DONE;
  537. }")
  538.  
  539.  
  540.  
  541. ;;
  542. ;;  ....................
  543. ;;
  544. ;;  Multiply instructions
  545. ;;
  546.  
  547. (define_expand "mulhi3"
  548.   [(set (match_operand:HI 0 "register_operand" "")
  549.     (mult:HI (match_operand:HI 1 "register_operand" "")
  550.          (match_operand:HI 2 "nonmemory_operand" "")))]
  551.   ""
  552.   "
  553. {
  554.   if (!dsp16xx_mulhi3_libcall)
  555.     dsp16xx_mulhi3_libcall = gen_rtx (SYMBOL_REF, Pmode, MULHI3_LIBCALL);
  556.  
  557.    emit_library_call (dsp16xx_mulhi3_libcall, 1, HImode, 2,
  558.               operands[1], HImode,
  559.               operands[2], HImode);
  560.    emit_move_insn (operands[0], hard_libcall_value(HImode));
  561.    DONE;
  562. }")
  563.  
  564. (define_insn "mulqi3"
  565.   [(set (match_operand:QI 0 "register_operand" "=w")
  566.         (mult:QI (match_operand:QI 1 "register_operand" "%x")
  567.                  (match_operand:QI 2 "register_operand" "y")))
  568.    (clobber (match_scratch:QI 3 "=v"))]
  569.   ""
  570.   "%m0=%1*%2"
  571.   [(set_attr "type" "malu_mul")])
  572.  
  573. (define_insn "mulqihi3"
  574.   [(set (match_operand:HI 0 "register_operand" "=t")
  575.         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%x"))
  576.                  (sign_extend:HI (match_operand:QI 2 "register_operand" "y"))))]
  577.   ""
  578.   "%0=%1*%2"
  579.   [(set_attr "type" "malu_mul")])
  580.  
  581. (define_insn "umulqihi3"
  582.   [(set (match_operand:HI 0 "register_operand" "=t")
  583.         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%x"))
  584.                  (zero_extend:HI (match_operand:QI 2 "register_operand" "y"))))]
  585.   ""
  586.   "%0=%1*%2"
  587.   [(set_attr "type" "malu_mul")])
  588.  
  589. (define_expand "mulhf3"
  590.   [(set (match_operand:HF 0 "register_operand" "")
  591.     (mult:HF (match_operand:HF 1 "register_operand" "")
  592.          (match_operand:HF 2 "nonmemory_operand" "")))]
  593.   ""
  594.   "
  595. {
  596.   if (!dsp16xx_mulhf3_libcall)
  597.     dsp16xx_mulhf3_libcall = gen_rtx (SYMBOL_REF, Pmode, MULHF3_LIBCALL);
  598.   
  599.   emit_library_call (dsp16xx_mulhf3_libcall, 1, HFmode, 2,
  600.              operands[1], HFmode,
  601.              operands[2], HFmode);
  602.   emit_move_insn (operands[0], hard_libcall_value(HFmode));
  603.   DONE;
  604. }")
  605.  
  606.  
  607.  
  608. ;;
  609. ;; *******************
  610. ;;
  611. ;; Divide Instructions
  612. ;;
  613.  
  614. (define_expand "divhi3"
  615.   [(set (match_operand:HI 0 "register_operand" "")
  616.     (div:HI (match_operand:HI 1 "register_operand" "")
  617.          (match_operand:HI 2 "nonmemory_operand" "")))]
  618.   ""
  619.   "
  620. {
  621.   if (!dsp16xx_divhi3_libcall)
  622.     dsp16xx_divhi3_libcall = gen_rtx (SYMBOL_REF, Pmode, DIVHI3_LIBCALL);
  623.  
  624.    emit_library_call (dsp16xx_divhi3_libcall, 1, HImode, 2,
  625.               operands[1], HImode,
  626.               operands[2], HImode);
  627.    emit_move_insn (operands[0], hard_libcall_value(HImode));
  628.    DONE;
  629. }")
  630.  
  631. (define_expand "udivhi3"
  632.   [(set (match_operand:HI 0 "register_operand" "")
  633.     (udiv:HI (match_operand:HI 1 "register_operand" "")
  634.          (match_operand:HI 2 "nonmemory_operand" "")))]
  635.   ""
  636.   "
  637. {
  638.   if (!dsp16xx_udivhi3_libcall)
  639.     dsp16xx_udivhi3_libcall = gen_rtx (SYMBOL_REF, Pmode, UDIVHI3_LIBCALL);
  640.   
  641.   emit_library_call (dsp16xx_udivhi3_libcall, 1, HImode, 2,
  642.              operands[1], HImode,
  643.              operands[2], HImode);
  644.   emit_move_insn (operands[0], hard_libcall_value(HImode));
  645.   DONE;
  646. }")
  647.  
  648. (define_expand "divqi3"
  649.   [(set (match_operand:QI 0 "register_operand" "")
  650.     (div:QI (match_operand:QI 1 "register_operand" "")
  651.          (match_operand:QI 2 "nonmemory_operand" "")))]
  652.   ""
  653.   "
  654. {
  655.   if (!dsp16xx_divqi3_libcall)
  656.     dsp16xx_divqi3_libcall = gen_rtx (SYMBOL_REF, Pmode, DIVQI3_LIBCALL);
  657.   
  658.   emit_library_call (dsp16xx_divqi3_libcall, 1, QImode, 2,
  659.              operands[1], QImode,
  660.              operands[2], QImode);
  661.   emit_move_insn (operands[0], hard_libcall_value(QImode));
  662.   DONE;
  663. }")
  664.  
  665. (define_expand "udivqi3"
  666.   [(set (match_operand:QI 0 "register_operand" "")
  667.     (udiv:QI (match_operand:QI 1 "register_operand" "")
  668.          (match_operand:QI 2 "nonmemory_operand" "")))]
  669.   ""
  670.   "
  671. {
  672.   if (!dsp16xx_udivqi3_libcall)
  673.     dsp16xx_udivqi3_libcall = gen_rtx (SYMBOL_REF, Pmode, UDIVQI3_LIBCALL);
  674.  
  675.    emit_library_call (dsp16xx_udivqi3_libcall, 1, QImode, 2,
  676.               operands[1], QImode,
  677.               operands[2], QImode);
  678.    emit_move_insn (operands[0], hard_libcall_value(QImode));
  679.    DONE;
  680. }")
  681.  
  682. ;;
  683. ;;  ....................
  684. ;;
  685. ;;  Modulo instructions
  686. ;;
  687. ;;  ....................
  688.  
  689. (define_expand "modhi3"
  690.   [(set (match_operand:HI 0 "register_operand" "")
  691.     (mod:HI (match_operand:HI 1 "register_operand" "")
  692.         (match_operand:HI 2 "nonmemory_operand" "")))]
  693.   ""
  694.   "
  695. {
  696.   if (!dsp16xx_modhi3_libcall)
  697.     dsp16xx_modhi3_libcall = gen_rtx (SYMBOL_REF, Pmode, MODHI3_LIBCALL);
  698.   
  699.   emit_library_call (dsp16xx_modhi3_libcall, 1, HImode, 2,
  700.              operands[1], HImode,
  701.              operands[2], HImode);
  702.   emit_move_insn (operands[0], hard_libcall_value(HImode));
  703.   DONE;
  704. }")
  705.  
  706. (define_expand "umodhi3"
  707.   [(set (match_operand:HI 0 "register_operand" "")
  708.     (umod:HI (match_operand:HI 1 "register_operand" "")
  709.          (match_operand:HI 2 "nonmemory_operand" "")))]
  710.   ""
  711.   "
  712. {
  713.   if (!dsp16xx_umodhi3_libcall)
  714.     dsp16xx_umodhi3_libcall = gen_rtx (SYMBOL_REF, Pmode, UMODHI3_LIBCALL);
  715.   
  716.   emit_library_call (dsp16xx_umodhi3_libcall, 1, HImode, 2,
  717.              operands[1], HImode,
  718.              operands[2], HImode);
  719.   emit_move_insn (operands[0], hard_libcall_value(HImode));
  720.   DONE;
  721. }")
  722.  
  723. (define_expand "modqi3"
  724.   [(set (match_operand:QI 0 "register_operand" "")
  725.     (mod:QI (match_operand:QI 1 "register_operand" "")
  726.         (match_operand:QI 2 "nonmemory_operand" "")))]
  727.   ""
  728.   "
  729. {
  730.   if (!dsp16xx_modqi3_libcall)
  731.     dsp16xx_modqi3_libcall = gen_rtx (SYMBOL_REF, Pmode, MODQI3_LIBCALL);
  732.   
  733.   emit_library_call (dsp16xx_modqi3_libcall, 1, QImode, 2,
  734.              operands[1], QImode,
  735.              operands[2], QImode);
  736.   emit_move_insn (operands[0], hard_libcall_value(QImode));
  737.   DONE;
  738. }")
  739.  
  740. (define_expand "umodqi3"
  741.   [(set (match_operand:QI 0 "register_operand" "")
  742.     (umod:QI (match_operand:QI 1 "register_operand" "")
  743.          (match_operand:QI 2 "nonmemory_operand" "")))]
  744.   ""
  745.   "
  746. {
  747.   if (!dsp16xx_umodqi3_libcall)
  748.     dsp16xx_umodqi3_libcall = gen_rtx (SYMBOL_REF, Pmode, UMODQI3_LIBCALL);
  749.   
  750.   emit_library_call (dsp16xx_umodqi3_libcall, 1, QImode, 2,
  751.              operands[1], QImode,
  752.              operands[2], QImode);
  753.   emit_move_insn (operands[0], hard_libcall_value(QImode));
  754.   DONE;
  755. }")
  756.  
  757. (define_expand "divhf3"
  758.   [(set (match_operand:HF 0 "register_operand" "")
  759.     (div:HF (match_operand:HF 1 "register_operand" "")
  760.         (match_operand:HF 2 "nonmemory_operand" "")))]
  761.   ""
  762.   "
  763. {
  764.   if (!dsp16xx_divhf3_libcall)
  765.     dsp16xx_divhf3_libcall = gen_rtx (SYMBOL_REF, Pmode, DIVHF3_LIBCALL);
  766.   
  767.   emit_library_call (dsp16xx_divhf3_libcall, 1, HFmode, 2,
  768.              operands[1], HFmode,
  769.              operands[2], HFmode);
  770.   emit_move_insn (operands[0], hard_libcall_value(HFmode));
  771.   DONE;
  772. }")
  773.  
  774.  
  775.  
  776. ;;
  777. ;; ********************
  778. ;;
  779. ;; Logical Instructions
  780. ;;
  781.  
  782. (define_insn "andhi3"
  783.   [(set (match_operand:HI 0 "register_operand" "=A,A,?A")
  784.         (and:HI (match_operand:HI 1 "register_operand" "%A,!A,A")
  785.                 (match_operand:HI 2 "nonmemory_operand" "Z,A,i")))]
  786.   ""
  787.   "@
  788.    %0=%1&%2
  789.    %0=%1&%2
  790.    %0=%w1&%H2\;%0=%b0&%U2"
  791.   [(set_attr "type" "f3_alu,f3_alu,f3_alu_i")])
  792.  
  793. (define_insn "andqi3"
  794.   [(set (match_operand:QI 0 "register_operand" "=k,u,uk,!k,!u,j,q,jq,!j,!q")
  795.     (and:QI (match_operand:QI 1 "register_operand" "uk,uk,uk,uk,uk,jq,jq,jq,jq,jq")
  796.         (match_operand:QI 2 "nonmemory_operand" "wz,wz,i,uk,uk,yv,yv,i,jq,jq")))
  797.     (clobber (match_scratch:QI 3 "=j,q,X,j,q,k,u,X,k,u"))]
  798.    ""
  799.    "@
  800.     %m0=%m1&%m2
  801.     %m0=%m1&%m2
  802.     %m0=%1&%H2
  803.     %m0=%m1&%m2
  804.     %m0=%m1&%m2
  805.     %m0=%m1&%m2
  806.     %m0=%m1&%m2
  807.     %m0=%b1&%H2
  808.     %m0=%m1&%m2
  809.     %m0=%m1&%m2")
  810.  
  811. (define_insn "iorhi3"
  812.   [(set (match_operand:HI 0 "register_operand" "=A,A,A,?A")
  813.         (ior:HI (match_operand:HI 1 "register_operand" "%A,!A,A,A")
  814.                 (match_operand:HI 2 "nonmemory_operand" "Z,A,I,i")))]
  815.  ""
  816.  "@
  817.    %0=%u1|%u2
  818.    %0=%u1|%u2
  819.    %0=%w1|%H2
  820.    %0=%w1|%H2\;%0=%b0|%U2"
  821.   [(set_attr "type" "f3_alu,f3_alu,f3_alu_i,f3_alu_i")])
  822.  
  823. (define_insn "iorqi3"
  824.   [(set (match_operand:QI 0 "register_operand" "=k,u,uk,!k,!u,j,q,jq,!j,!q")
  825.     (ior:QI (match_operand:QI 1 "register_operand" "uk,uk,uk,uk,uk,jq,jq,jq,jq,jq")
  826.         (match_operand:QI 2 "nonmemory_operand" "wz,wz,i,uk,uk,yv,yv,i,jq,jq")))
  827.     (clobber (match_scratch:QI 3 "=j,q,X,j,q,k,u,X,k,u"))]
  828.    ""
  829.    "@
  830.     %m0=%m1|%m2
  831.     %m0=%m1|%m2
  832.     %m0=%1|%H2
  833.     %m0=%m1|%m2
  834.     %m0=%m1|%m2
  835.     %m0=%m1|%m2
  836.     %m0=%m1|%m2
  837.     %m0=%b1|%H2
  838.     %m0=%m1|%m2
  839.     %m0=%m1|%m2")
  840.  
  841. (define_insn "xorhi3"
  842.   [(set (match_operand:HI 0 "register_operand" "=A,A,A,?A")
  843.         (xor:HI (match_operand:HI 1 "register_operand" "%A,!A,A,A")
  844.                 (match_operand:HI 2 "nonmemory_operand" "Z,A,I,i")))]
  845.   ""
  846.   "@
  847.    %0=%1^%2
  848.    %0=%1^%2
  849.    %0=%w1^%H2
  850.    %0=%w1^%H2\;%0=%b0^%U2"
  851.   [(set_attr "type" "f3_alu,f3_alu,f3_alu_i,f3_alu_i")])
  852.  
  853. (define_insn "xorqi3"
  854.   [(set (match_operand:QI 0 "register_operand" "=k,u,uk,!k,!u,j,q,jq,!j,!q")
  855.     (xor:QI (match_operand:QI 1 "register_operand" "uk,uk,uk,uk,uk,jq,jq,jq,jq,jq")
  856.         (match_operand:QI 2 "nonmemory_operand" "wz,wz,i,uk,uk,yv,yv,i,jq,jq")))
  857.     (clobber (match_scratch:QI 3 "=j,q,X,j,q,k,u,X,k,u"))]
  858.    ""
  859.    "@
  860.     %m0=%m1^%m2
  861.     %m0=%m1^%m2
  862.     %m0=%1^%H2
  863.     %m0=%m1^%m2
  864.     %m0=%m1^%m2
  865.     %m0=%m1^%m2
  866.     %m0=%m1^%m2
  867.     %m0=%b1^%H2
  868.     %m0=%m1^%m2
  869.     %m0=%m1^%m2")
  870.  
  871. (define_insn "one_cmplhi2"
  872.   [(set (match_operand:HI 0 "register_operand" "=A")
  873.         (not:HI (match_operand:HI 1 "register_operand" "A")))]
  874.   ""
  875.   "%0= ~%1"
  876.   [(set_attr "type" "special")])
  877.  
  878. (define_insn "one_cmplqi2"
  879.   [(set (match_operand:QI 0 "register_operand" "=ku,jq")
  880.         (not:QI (match_operand:QI 1 "register_operand" "ku,jq")))]
  881.   ""
  882.   "@
  883.    %m0= %1 ^ 0xffff
  884.    %m0= %b1 ^ 0xffff"
  885.   [(set_attr "type" "special")])
  886.  
  887.  
  888. ;;
  889. ;; MOVE INSTRUCTIONS
  890. ;;
  891.  
  892. (define_expand "movhi"
  893.   [(set (match_operand:HI 0 "general_operand" "")
  894.     (match_operand:HI 1 "general_operand" ""))]
  895.   ""
  896.   "
  897. {
  898.   if (emit_move_sequence (operands, HImode))
  899.     DONE;
  900. }")
  901.  
  902.  
  903. (define_insn "match_movhi1"
  904.   [(set (match_operand:HI 0 "nonimmediate_operand"  "=A,Z,A,d,d,m,?d,*Y,t,f")
  905.     (match_operand:HI 1 "general_operand"        "d,A,K,i,m,d,*Y,?d,t,f"))]
  906.   "register_operand(operands[0], HImode)
  907.    || register_operand(operands[1], HImode)"
  908.   "*
  909. {
  910.     switch (which_alternative)
  911.         {
  912.         /* register to accumulator */
  913.         case 0:
  914.             return \"%0=%1\";
  915.         case 1:
  916.            return \"%u0=%u1\;%w0=%w1\";
  917.             case 2:
  918.                return \"%0=%0^%0\";
  919.         case 3:
  920.              return \"%u0=%U1\;%w0=%H1\";
  921.         case 4:
  922.            double_reg_from_memory(operands);
  923.            return \"\";
  924.         case 5:
  925.            double_reg_to_memory(operands);
  926.            return \"\";
  927.         case 6:
  928.         case 7:
  929.            return \"%u0=%u1\;%w0=%w1\";
  930.         case 8:
  931.         case 9:
  932.            return \"\";
  933.         }
  934. }"
  935. [(set_attr "type" "move,move,load_i,load_i,load,store,load,store,move,move")])
  936.  
  937.  
  938. ;; NOTE: It is cheaper to do 'y = *r0', than 'r0 = *r0'.
  939.  
  940. (define_expand "movqi"
  941.   [(set (match_operand:QI 0 "nonimmediate_operand" "")
  942.     (match_operand:QI 1 "general_operand" ""))]
  943.   ""
  944.   "
  945. {
  946.   if (emit_move_sequence (operands, QImode))
  947.     DONE;
  948. }")
  949.  
  950. ;; The movqi pattern with the parallel is used for addqi insns (which have a parallel)
  951. ;; that are turned into moveqi insns by the flow phase. This happens when a auto-increment
  952. ;; is detected.
  953.  
  954. (define_insn "match_movqi1"
  955.   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "=A,r,aW,c,?D,m<>,e,Y,r,xyz,m<>")
  956.            (match_operand:QI 1 "general_operand"       "r,A,J,i,m<>,D,Y,e,0,m<>,xyz"))
  957.           (clobber (match_scratch:QI 2 "=X,X,X,X,X,X,X,X,X,X,X"))])]
  958.   "register_operand(operands[0], QImode)
  959.    || register_operand(operands[1], QImode)"
  960.   "*
  961. {
  962.     switch (which_alternative)
  963.     {
  964.         case 0:
  965.            /* We have to use the move mneumonic otherwise the 1610 will
  966.               attempt to transfer all 32-bits of 'y', 'p' or an accumualtor
  967.               , which we don't want */
  968.            if (REGNO(operands[1]) == REG_Y || REGNO(operands[1]) == REG_PROD
  969.             || IS_ACCUM_REG(REGNO(operands[1])))
  970.                return \"move %0=%1\";
  971.            else
  972.                return \"%0=%1\";
  973.  
  974.         case 1:
  975.             return \"%0=%1\";
  976.  
  977.         case 2:
  978.            return \"set %0=%H1\";
  979.  
  980.         case 3:
  981.                    return \"%0=%H1\";
  982.  
  983.         case 4:
  984.            return \"%0=%1\";
  985.  
  986.         case 5:
  987.         case 6:
  988.                    return \"%0=%1\";
  989.  
  990.         case 7:
  991.            return \"%0=%1\";
  992.  
  993.         case 8:
  994.            return \"\";
  995.  
  996.                 case 9: case 10:
  997.            return \"%0=%1\";
  998.     }
  999. }")
  1000.  
  1001. (define_insn "match_movqi2"
  1002.   [(set (match_operand:QI 0 "nonimmediate_operand" "=A,r,aW,c,?D,m<>,e,Y,r,xyz,m<>")
  1003.     (match_operand:QI 1 "general_operand"       "r,A,J,i,m<>,D,Y,e,0,m<>,xyz"))]
  1004.   "register_operand(operands[0], QImode)
  1005.    || register_operand(operands[1], QImode)"
  1006.   "*
  1007. {
  1008.     switch (which_alternative)
  1009.     {
  1010.         case 0:
  1011.            /* We have to use the move mneumonic otherwise the 1610 will
  1012.               attempt to transfer all 32-bits of 'y', 'p' or an accumualtor
  1013.               , which we don't want */
  1014.            if (REGNO(operands[1]) == REG_Y || REGNO(operands[1]) == REG_PROD
  1015.             || IS_ACCUM_REG(REGNO(operands[1])))
  1016.                return \"move %0=%1\";
  1017.            else
  1018.                return \"%0=%1\";
  1019.  
  1020.         case 1:
  1021.             return \"%0=%1\";
  1022.  
  1023.         case 2:
  1024.            return \"set %0=%H1\";
  1025.  
  1026.         case 3:
  1027.                    return \"%0=%H1\";
  1028.  
  1029.         case 4:
  1030.            return \"%0=%1\";
  1031.  
  1032.         case 5:
  1033.         case 6:
  1034.                    return \"%0=%1\";
  1035.  
  1036.         case 7:
  1037.            return \"%0=%1\";
  1038.  
  1039.         case 8:
  1040.            return \"\";
  1041.  
  1042.                 case 9: case 10:
  1043.            return \"%0=%1\";
  1044.     }
  1045. }")
  1046.  
  1047. (define_expand "reload_inqi"
  1048.   [(set (match_operand:QI 0 "register_operand" "=u")
  1049.         (match_operand:QI 1 "sp_operand" ""))
  1050.    (clobber (match_operand:QI 2 "register_operand" "=&q"))]
  1051.   ""
  1052.   "
  1053. {
  1054.   rtx addr_reg = XEXP (operands[1], 0);
  1055.   rtx offset = XEXP (operands[1], 1);
  1056.  
  1057.   /* First, move the frame or stack pointer to the accumulator */
  1058.   emit_move_insn (operands[0], addr_reg);
  1059.  
  1060.   /* Then generate the add insn */
  1061.   emit_insn (gen_rtx (PARALLEL, VOIDmode, 
  1062.               gen_rtvec (2,
  1063.                  gen_rtx (SET, VOIDmode, operands[0], 
  1064.                       gen_rtx (PLUS, QImode, operands[0], offset)),
  1065.                  gen_rtx (CLOBBER, VOIDmode, operands[2]))));
  1066.   DONE;
  1067. }")
  1068.  
  1069. (define_expand "reload_inhi"
  1070.   [(set (match_operand:HI 0 "register_operand" "=r")
  1071.         (match_operand:HI 1 "register_operand" "r"))
  1072.    (clobber (match_operand:QI 2 "register_operand" "=&h"))]
  1073.   ""
  1074.   "
  1075. {
  1076.   /* Check for an overlap of operand 2 (an accumulator) with
  1077.      the msw of operand 0. If we have an overlap we must reverse
  1078.      the order of the moves. */
  1079.  
  1080.   if (REGNO(operands[2]) == REGNO(operands[0]))
  1081.     {
  1082.       emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HImode));
  1083.       emit_move_insn (operand_subword (operands[0], 1, 0, HImode), operands[2]);
  1084.       emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HImode));
  1085.       emit_move_insn (operand_subword (operands[0], 0, 0, HImode), operands[2]);
  1086.     }
  1087.   else
  1088.     {
  1089.       emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HImode));
  1090.       emit_move_insn (operand_subword (operands[0], 0, 0, HImode), operands[2]);
  1091.       emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HImode));
  1092.       emit_move_insn (operand_subword (operands[0], 1, 0, HImode), operands[2]);
  1093.     }
  1094.  
  1095.   DONE;
  1096. }")
  1097.  
  1098.  
  1099. (define_expand "reload_outhi"
  1100.   [(set (match_operand:HI 0 "register_operand" "=r")
  1101.         (match_operand:HI 1 "register_operand" "r"))
  1102.    (clobber (match_operand:QI 2 "register_operand" "=&h"))]
  1103.   ""
  1104.   "
  1105. {
  1106.     emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HImode));
  1107.     emit_move_insn (operand_subword (operands[0], 0, 0, HImode), operands[2]);
  1108.     emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HImode));
  1109.     emit_move_insn (operand_subword (operands[0], 1, 0, HImode), operands[2]);
  1110.     DONE;
  1111. }")
  1112.  
  1113. (define_expand "movstrqi"
  1114.   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
  1115.            (match_operand:BLK 1 "memory_operand" ""))
  1116.           (use (match_operand:QI 2 "const_int_operand" ""))
  1117.           (use (match_operand:QI 3 "const_int_operand" ""))
  1118.           (clobber (match_scratch:QI 4 ""))
  1119.           (clobber (match_dup 5))
  1120.           (clobber (match_dup 6))])]
  1121.   ""
  1122.   "
  1123. {
  1124.   rtx addr0, addr1;
  1125.  
  1126.   if (GET_CODE (operands[2]) != CONST_INT)
  1127.     FAIL;
  1128.  
  1129.   if (INTVAL(operands[2]) > 127)
  1130.     FAIL;
  1131.  
  1132.   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
  1133.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  1134.  
  1135.   operands[5] = addr0;
  1136.   operands[6] = addr1;
  1137.  
  1138.   operands[0] = gen_rtx (MEM, BLKmode, addr0);
  1139.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  1140. }")
  1141.  
  1142. (define_insn ""
  1143.   [(set (mem:BLK (match_operand:QI 0 "register_operand" "a"))
  1144.     (mem:BLK (match_operand:QI 1 "register_operand" "a")))
  1145.    (use (match_operand:QI 2 "const_int_operand" "n"))
  1146.    (use (match_operand:QI 3 "immediate_operand" "i"))
  1147.    (clobber (match_scratch:QI 4 "=x"))
  1148.    (clobber (match_dup 0))
  1149.    (clobber (match_dup 1))]
  1150.   ""
  1151.   "*
  1152. { return output_block_move (operands); }")
  1153.  
  1154.  
  1155. ;; Floating point move insns
  1156.  
  1157.  
  1158. (define_expand "movhf"
  1159.   [(set (match_operand:HF 0 "general_operand" "")
  1160.     (match_operand:HF 1 "general_operand" ""))]
  1161.   ""
  1162.   "
  1163. {
  1164.   if (emit_move_sequence (operands, HFmode))
  1165.     DONE;
  1166. }")
  1167.  
  1168. (define_insn "match_movhf"
  1169.   [(set (match_operand:HF 0 "nonimmediate_operand" "=A,Z,d,d,m,d,Y")
  1170.     (match_operand:HF 1 "general_operand"       "d,A,F,m,d,Y,d"))]
  1171.   ""
  1172.   "*
  1173. {
  1174.     /* NOTE: When loading the register 16 bits at a time we
  1175.        MUST load the high half FIRST (because the 1610 zeros
  1176.        the low half) and then load the low half */
  1177.  
  1178.     switch (which_alternative)
  1179.         {
  1180.         /* register to accumulator */
  1181.         case 0:
  1182.             return \"%0=%1\";
  1183.         case 1:
  1184.            return \"%u0=%u1\;%w0=%w1\";
  1185.         case 2:
  1186.            output_dsp16xx_float_const(operands);
  1187.            return \"\";
  1188.         case 3:
  1189.            double_reg_from_memory(operands);
  1190.            return \"\";
  1191.         case 4:
  1192.            double_reg_to_memory(operands);
  1193.            return \"\";
  1194.         case 5:
  1195.         case 6:
  1196.            return \"%u0=%u1\;%w0=%w1\";
  1197.         }
  1198. }"
  1199. [(set_attr "type" "move,move,load_i,load,store,load,store")])
  1200.  
  1201.  
  1202.  
  1203. (define_expand "reload_inhf"
  1204.   [(set (match_operand:HF 0 "register_operand" "=r")
  1205.         (match_operand:HF 1 "register_operand" "r"))
  1206.    (clobber (match_operand:QI 2 "register_operand" "=&h"))]
  1207.   ""
  1208.   "
  1209. {
  1210.   /* Check for an overlap of operand 2 (an accumulator) with
  1211.      the msw of operand 0. If we have an overlap we must reverse
  1212.      the order of the moves. */
  1213.  
  1214.   if (REGNO(operands[2]) == REGNO(operands[0]))
  1215.     {
  1216.       emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HFmode));
  1217.       emit_move_insn (operand_subword (operands[0], 1, 0, HFmode), operands[2]);
  1218.       emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HFmode));
  1219.       emit_move_insn (operand_subword (operands[0], 0, 0, HFmode), operands[2]);
  1220.     }
  1221.   else
  1222.     {
  1223.       emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HFmode));
  1224.       emit_move_insn (operand_subword (operands[0], 0, 0, HFmode), operands[2]);
  1225.       emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HFmode));
  1226.       emit_move_insn (operand_subword (operands[0], 1, 0, HFmode), operands[2]);
  1227.     }
  1228.   
  1229.   DONE;
  1230. }")
  1231.  
  1232. (define_expand "reload_outhf"
  1233.   [(set (match_operand:HF 0 "register_operand" "=r")
  1234.         (match_operand:HF 1 "register_operand" "r"))
  1235.    (clobber (match_operand:QI 2 "register_operand" "=&h"))]
  1236.   ""
  1237.   "
  1238. {
  1239.     emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HFmode));
  1240.     emit_move_insn (operand_subword (operands[0], 0, 0, HFmode), operands[2]);
  1241.     emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HFmode));
  1242.     emit_move_insn (operand_subword (operands[0], 1, 0, HFmode), operands[2]);
  1243.     DONE;
  1244. }")
  1245.  
  1246.  
  1247. ;;
  1248. ;; CONVERSION INSTRUCTIONS
  1249. ;;
  1250.  
  1251. (define_expand "extendqihi2"
  1252.   [(clobber (match_dup 2))
  1253.    (set (match_dup 3) (match_operand:QI 1 "register_operand" ""))
  1254.    (set (match_operand:HI 0 "register_operand" "")
  1255.     (ashift:HI (match_dup 2)
  1256.            (const_int 16)))
  1257.    (set (match_dup 0)
  1258.     (ashiftrt:HI (match_dup 0) (const_int 16)))]
  1259.   ""
  1260.   "
  1261. {
  1262.     operands[2] = gen_reg_rtx (HImode);
  1263.     operands[3] = gen_rtx (SUBREG, QImode, operands[2], 1);
  1264. }")
  1265.  
  1266. ;;(define_insn "extendqihi2"
  1267. ;;  [(set (match_operand:HI 0 "register_operand" "=A")
  1268. ;;        (sign_extend:HI (match_operand:QI 1 "register_operand" "h")))]
  1269. ;;  ""
  1270. ;;  "%0 = %1 >> 16")
  1271.  
  1272. ;;(define_insn "zero_extendqihi2"
  1273. ;;  [(set (match_operand:HI 0 "register_operand" "=t,f,A,?d,?A")
  1274. ;;        (zero_extend:HI (match_operand:QI 1 "register_operand" "w,z,ku,A,r")))]
  1275. ;;  ""
  1276. ;;  "*
  1277. ;; {
  1278. ;;  switch (which_alternative)
  1279. ;;    {
  1280. ;;    case 0:
  1281. ;;    case 1:
  1282. ;;      return \"%0=0\";
  1283. ;;
  1284. ;;    case 2:
  1285. ;;      if (REGNO(operands[1]) == (REGNO(operands[0]) + 1))
  1286. ;;        return \"%0=0\";
  1287. ;;      else
  1288. ;;    return \"%w0=%1\;%0=0\";
  1289. ;;    case 3:
  1290. ;;      return \"%w0=%1\;%0=0\";
  1291. ;;
  1292. ;;    case 4:
  1293. ;;      if (REGNO(operands[1]) == REG_Y || REGNO(operands[1]) == REG_PROD
  1294. ;;      || IS_ACCUM_REG(REGNO(operands[1])))
  1295. ;;    return \"move %w0=%1\;%0=0\";
  1296. ;;      else
  1297. ;;    return \"%w0=%1\;%0=0\";
  1298. ;;    }
  1299. ;; }")
  1300.  
  1301. (define_expand "zero_extendqihi2"
  1302.   [(clobber (match_dup 2))
  1303.    (set (match_dup 3) (match_operand:QI 1 "register_operand" ""))
  1304.    (set (match_operand:HI 0 "register_operand" "")
  1305.     (ashift:HI (match_dup 2)
  1306.            (const_int 16)))
  1307.    (set (match_dup 0)
  1308.     (lshiftrt:HI (match_dup 0) (const_int 16)))]
  1309.   ""
  1310.   "
  1311. {
  1312.     operands[2] = gen_reg_rtx (HImode);
  1313.     operands[3] = gen_rtx (SUBREG, QImode, operands[2], 1);
  1314. }")
  1315.  
  1316.  
  1317. (define_expand "floathihf2"
  1318.   [(set (match_operand:HF 0 "register_operand" "")
  1319.     (float:HF (match_operand:HI 1 "register_operand" "")))]
  1320.   ""
  1321.   "
  1322. {
  1323.   if (!dsp16xx_floathihf2_libcall)
  1324.     dsp16xx_floathihf2_libcall = gen_rtx (SYMBOL_REF, Pmode, FLOATHIHF2_LIBCALL);
  1325.   
  1326.   emit_library_call (dsp16xx_floathihf2_libcall, 1, HFmode, 1,
  1327.              operands[1], HImode);
  1328.   emit_move_insn (operands[0], hard_libcall_value(HFmode));
  1329.   DONE;
  1330. }")
  1331.  
  1332. (define_expand "fix_trunchfhi2"
  1333.   [(set (match_operand:HI 0 "register_operand" "")
  1334.     (fix:HI (match_operand:HF 1 "register_operand" "")))]
  1335.   ""
  1336.   "
  1337. {
  1338.   if (!dsp16xx_fixhfhi2_libcall)
  1339.     dsp16xx_fixhfhi2_libcall = gen_rtx (SYMBOL_REF, Pmode, FIXHFHI2_LIBCALL);
  1340.   
  1341.   emit_library_call (dsp16xx_fixhfhi2_libcall, 1, HImode, 1,
  1342.              operands[1], HFmode);
  1343.   emit_move_insn (operands[0], hard_libcall_value(HImode));
  1344.   DONE;
  1345. }")
  1346.  
  1347. (define_expand "fixuns_trunchfhi2"
  1348.   [(set (match_operand:HI 0 "register_operand" "")
  1349.     (unsigned_fix:HI (match_operand:HF 1 "register_operand" "")))]
  1350.   ""
  1351.   "
  1352. {
  1353.   rtx reg1 = gen_reg_rtx (HFmode);
  1354.   rtx reg2 = gen_reg_rtx (HFmode);
  1355.   rtx reg3 = gen_reg_rtx (HImode);
  1356.   rtx label1 = gen_label_rtx ();
  1357.   rtx label2 = gen_label_rtx ();
  1358.   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
  1359.  
  1360.   if (reg1)            /* turn off complaints about unreached code */
  1361.     {
  1362.       emit_move_insn (reg1, immed_real_const_1 (offset, HFmode));
  1363.       do_pending_stack_adjust ();
  1364.  
  1365.       emit_insn (gen_cmphf (operands[1], reg1));
  1366.       emit_jump_insn (gen_bge (label1));
  1367.  
  1368.       emit_insn (gen_fix_trunchfhi2 (operands[0], operands[1]));
  1369.       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
  1370.                    gen_rtx (LABEL_REF, VOIDmode, label2)));
  1371.       emit_barrier ();
  1372.  
  1373.       emit_label (label1);
  1374.       emit_insn (gen_subhf3 (reg2, operands[1], reg1));
  1375.       emit_move_insn (reg3, GEN_INT (0x80000000));;
  1376.  
  1377.       emit_insn (gen_fix_trunchfhi2 (operands[0], reg2));
  1378.       emit_insn (gen_iorhi3 (operands[0], operands[0], reg3));
  1379.  
  1380.       emit_label (label2);
  1381.  
  1382.       /* allow REG_NOTES to be set on last insn (labels don't have enough
  1383.      fields, and can't be used for REG_NOTES anyway).  */
  1384.       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
  1385.       DONE;
  1386.     }
  1387. }")
  1388.  
  1389. ;;
  1390. ;; SHIFT INSTRUCTIONS
  1391. ;;
  1392.  
  1393. (define_insn ""
  1394.   [(set (match_operand:HI 0 "register_operand" "=A")
  1395.         (ashiftrt:HI (match_operand:HI 1 "register_operand" "A")
  1396.                      (const_int 1)))]
  1397.   ""
  1398.   "%0=%1>>1"
  1399.   [(set_attr "type" "special")])
  1400.  
  1401. (define_insn ""
  1402.   [(set (match_operand:HI 0 "register_operand" "=A")
  1403.         (ashiftrt:HI (match_operand:HI 1 "register_operand" "A")
  1404.                      (const_int 4)))]
  1405.   ""
  1406.   "%0=%1>>4"
  1407.   [(set_attr "type" "special")])
  1408.  
  1409. (define_insn ""
  1410.   [(set (match_operand:HI 0 "register_operand" "=A")
  1411.         (ashiftrt:HI (match_operand:HI 1 "register_operand" "A")
  1412.                      (const_int 8)))]
  1413.   ""
  1414.   "%0=%1>>8"
  1415.   [(set_attr "type" "special")])
  1416.  
  1417. (define_insn ""
  1418.   [(set (match_operand:HI 0 "register_operand" "=A")
  1419.         (ashiftrt:HI (match_operand:HI 1 "register_operand" "A")
  1420.                      (const_int 16)))]
  1421.   ""
  1422.   "%0=%1>>16"
  1423.   [(set_attr "type" "special")])
  1424.  
  1425. ;;
  1426. ;; Arithmetic Right shift
  1427.  
  1428. (define_expand "ashrhi3"
  1429.   [(set (match_operand:HI 0 "register_operand" "")
  1430.         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
  1431.                      (match_operand:QI 2 "nonmemory_operand" "")))]
  1432.   ""
  1433.   "
  1434. {
  1435.   if (!TARGET_BMU)
  1436.   {
  1437.       /* If we are shifting by a constant we can do it in 1 or more
  1438.      1600 core shift instructions. The core instructions can
  1439.      shift by 1, 4, 8, or 16. */
  1440.       
  1441.       if (GET_CODE(operands[2]) == CONST_INT)
  1442.     ;
  1443.       else
  1444.       {
  1445.     rtx label1 = gen_label_rtx ();
  1446.     rtx label2 = gen_label_rtx ();
  1447.  
  1448. #if 0
  1449.     if (!dsp16xx_ashrhi3_libcall)
  1450.       dsp16xx_ashrhi3_libcall = gen_rtx (SYMBOL_REF, Pmode, ASHRHI3_LIBCALL);
  1451.  
  1452.       emit_library_call (dsp16xx_ashrhi3_libcall, 1, HImode, 2,
  1453.                  operands[1], HImode,
  1454.                  operands[2], QImode);
  1455.       emit_move_insn (operands[0], hard_libcall_value(HImode));
  1456.       DONE;
  1457. #else
  1458.     do_pending_stack_adjust ();
  1459.     emit_insn (gen_tstqi (operands[2]));
  1460.     emit_jump_insn (gen_bne (label1));
  1461.     emit_move_insn (operands[0], operands[1]);
  1462.     emit_jump_insn (gen_jump (label2));
  1463.     emit_barrier ();
  1464.     emit_label (label1);
  1465.  
  1466.     if (GET_CODE(operands[2]) != MEM)
  1467.       {
  1468.         rtx stack_slot;
  1469.         
  1470.         stack_slot = assign_stack_temp (QImode, GET_MODE_SIZE(QImode), 0);
  1471.         stack_slot = change_address (stack_slot, VOIDmode, XEXP (stack_slot, 0));
  1472.         emit_move_insn (stack_slot, operands[2]);
  1473.         operands[2] = stack_slot;
  1474.       }
  1475.  
  1476.     emit_insn (gen_match_ashrhi3_nobmu (operands[0], operands[1], operands[2]));
  1477.     emit_label (label2);
  1478.     DONE;
  1479. #endif
  1480.       }
  1481.   }
  1482. }")
  1483.  
  1484. (define_insn "match_ashrhi3_bmu"
  1485.   [(set (match_operand:HI 0 "register_operand" "=A,A,A")
  1486.         (ashiftrt:HI (match_operand:HI 1 "register_operand" "A,A,!A")
  1487.                      (match_operand:QI 2 "nonmemory_operand" "B,I,h")))]
  1488.   "TARGET_BMU"
  1489.   "@
  1490.    %0=%1>>%2
  1491.    %0=%1>>%H2
  1492.    %0=%1>>%2"
  1493.   [(set_attr "type" "shift,shift_i,shift")])
  1494.  
  1495. (define_insn "match_ashrhi3_nobmu"
  1496.   [(set (match_operand:HI 0 "register_operand" "=A,A")
  1497.         (ashiftrt:HI (match_operand:HI 1 "register_operand" "A,0")
  1498.                      (match_operand:QI 2 "general_operand" "n,m")))]
  1499.   "!TARGET_BMU"
  1500.   "*
  1501. {
  1502.   if (which_alternative == 0)
  1503.     {
  1504.       emit_1600_core_shift (ASHIFTRT, operands, INTVAL(operands[2]));
  1505.       return \"\";
  1506.     }
  1507.   else
  1508.     {
  1509.       output_asm_insn (\"cloop=%2\", operands);
  1510.       output_asm_insn (\"do 0 \{\", operands);
  1511.       output_asm_insn (\"%0=%0>>1\", operands);
  1512.       return \"\}\";
  1513.     }
  1514. }")
  1515.            
  1516.  
  1517.  
  1518. ;;
  1519. ;; Logical Right Shift
  1520.  
  1521. (define_insn ""
  1522.   [(set (match_operand:HI 0 "register_operand" "=A")
  1523.         (lshiftrt:HI (match_operand:HI 1 "register_operand" "A")
  1524.                      (const_int 1)))]
  1525.   ""
  1526.   "%0=%1>>1\;%0=%b0&0x7fff"
  1527.   [(set_attr "type" "special")])
  1528.  
  1529. (define_insn ""
  1530.   [(set (match_operand:HI 0 "register_operand" "=A")
  1531.         (lshiftrt:HI (match_operand:HI 1 "register_operand" "A")
  1532.                      (const_int 4)))]
  1533.   ""
  1534.   "%0=%1>>4\;%0=%b0&0x0fff"
  1535.   [(set_attr "type" "special")])
  1536.  
  1537. (define_insn ""
  1538.   [(set (match_operand:HI 0 "register_operand" "=A")
  1539.         (lshiftrt:HI (match_operand:HI 1 "register_operand" "A")
  1540.                      (const_int 8)))]
  1541.   ""
  1542.   "%0=%1>>8\;%0=%b0&0x00ff"
  1543.   [(set_attr "type" "special")])
  1544.  
  1545. (define_insn ""
  1546.   [(set (match_operand:HI 0 "register_operand" "=A")
  1547.         (lshiftrt:HI (match_operand:HI 1 "register_operand" "A")
  1548.                      (const_int 16)))]
  1549.   ""
  1550.   "%0=%1>>16\;%0=%b0&0x0000"
  1551.   [(set_attr "type" "special")])
  1552.  
  1553. (define_expand "lshrhi3"
  1554.   [(set (match_operand:HI 0 "register_operand" "")
  1555.         (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
  1556.                      (match_operand:QI 2 "nonmemory_operand" "")))]
  1557.   ""
  1558.   "
  1559. {
  1560.   if (!TARGET_BMU)
  1561.     {
  1562.       /* If we are shifting by a constant we can do it in 1 or more
  1563.      1600 core shift instructions. The core instructions can
  1564.      shift by 1, 4, 8, or 16. */
  1565.       
  1566.       if (GET_CODE(operands[2]) == CONST_INT)
  1567.     emit_insn (gen_match_lshrhi3_nobmu (operands[0], operands[1], operands[2]));    
  1568.       else
  1569.     {
  1570.       rtx label1 = gen_label_rtx ();
  1571.       rtx label2 = gen_label_rtx ();
  1572. #if 0
  1573.       if (!dsp16xx_lshrhi3_libcall)
  1574.         dsp16xx_lshrhi3_libcall = gen_rtx (SYMBOL_REF, Pmode, LSHRHI3_LIBCALL);
  1575.       
  1576.       emit_library_call (dsp16xx_lshrhi3_libcall, 1, HImode, 2,
  1577.                  operands[1], HImode,
  1578.                  operands[2], QImode);
  1579.       emit_move_insn (operands[0], hard_libcall_value(HImode));
  1580.       DONE;
  1581. #else
  1582.       do_pending_stack_adjust ();
  1583.       emit_insn (gen_tstqi (operands[2]));
  1584.       emit_jump_insn (gen_bne (label1));
  1585.       emit_move_insn (operands[0], operands[1]);
  1586.       emit_jump_insn (gen_jump (label2));
  1587.       emit_barrier ();
  1588.       emit_label (label1);
  1589.  
  1590.       if (GET_CODE(operands[2]) != MEM)
  1591.         {
  1592.           rtx stack_slot;
  1593.         
  1594.           stack_slot = assign_stack_temp (QImode, GET_MODE_SIZE(QImode), 0);
  1595.           stack_slot = change_address (stack_slot, VOIDmode, XEXP (stack_slot, 0));
  1596.           emit_move_insn (stack_slot, operands[2]);
  1597.           operands[2] = stack_slot;
  1598.         }
  1599.  
  1600.       emit_insn (gen_match_lshrhi3_nobmu (operands[0], operands[1], operands[2]));
  1601.       emit_label (label2);
  1602.       DONE;
  1603. #endif
  1604.     }
  1605.     }
  1606. }")
  1607.  
  1608. (define_insn "match_lshrhi3"
  1609.   [(set (match_operand:HI 0 "register_operand" "=A,A,A")
  1610.         (lshiftrt:HI (match_operand:HI 1 "register_operand" "A,A,!A")
  1611.                      (match_operand:QI 2 "nonmemory_operand" "B,I,h")))]
  1612.   "TARGET_BMU"
  1613.   "@
  1614.    %0=%1>>>%2
  1615.    %0=%1>>>%H2
  1616.    %0=%1>>>%2"
  1617.   [(set_attr "type" "shift,shift_i,shift")])
  1618.  
  1619. (define_insn "match_lshrhi3_nobmu"
  1620.   [(set (match_operand:HI 0 "register_operand" "=A,A")
  1621.         (lshiftrt:HI (match_operand:HI 1 "register_operand" "A,0")
  1622.                      (match_operand:QI 2 "general_operand" "n,m")))
  1623.    (clobber (match_scratch:QI 3 "=X,Y"))]
  1624.   "!TARGET_BMU"
  1625.   "*
  1626. {
  1627.   if (which_alternative == 0)
  1628.     {
  1629.       emit_1600_core_shift (LSHIFTRT, operands, INTVAL(operands[2]));
  1630.       return \"\";
  1631.     }
  1632.   else
  1633.     {
  1634.       output_asm_insn (\"%3=psw\;psw=0\",operands);
  1635.       output_asm_insn (\"cloop=%2\", operands);
  1636.       output_asm_insn (\"do 0 \{\", operands);
  1637.       output_asm_insn (\"%0=%0>>1\", operands);
  1638.       output_asm_insn (\"\}\", operands);
  1639.       return \"psw=%3\";
  1640.     }
  1641. }")
  1642.  
  1643.  
  1644. ;;
  1645. ;; Arithmetic Left shift
  1646.  
  1647. ;; Start off with special case arithmetic left shift by 1,4,8 or 16.
  1648.  
  1649.  
  1650. (define_insn ""
  1651.   [(set (match_operand:HI 0 "register_operand" "=A")
  1652.         (ashift:HI (match_operand:HI 1 "register_operand" "A")
  1653.                    (const_int 1)))]
  1654.   ""
  1655.   "%0=%1<<1"
  1656.   [(set_attr "type" "special")])
  1657.  
  1658. (define_insn ""
  1659.   [(set (match_operand:HI 0 "register_operand" "=A")
  1660.         (ashift:HI (match_operand:HI 1 "register_operand" "A")
  1661.                    (const_int 4)))]
  1662.   ""
  1663.   "%0=%1<<4"
  1664.   [(set_attr "type" "special")])
  1665.  
  1666. (define_insn ""
  1667.   [(set (match_operand:HI 0 "register_operand" "=A")
  1668.         (ashift:HI (match_operand:HI 1 "register_operand" "A")
  1669.                    (const_int 8)))]
  1670.   ""
  1671.   "%0=%1<<8"
  1672.   [(set_attr "type" "special")])
  1673.  
  1674. (define_insn ""
  1675.   [(set (match_operand:HI 0 "register_operand" "=A")
  1676.     (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "A"))
  1677.            (const_int 16)))]
  1678.   ""
  1679.   "%0=%1<<16"
  1680.   [(set_attr "type" "special")])
  1681.  
  1682. (define_insn ""
  1683.   [(set (match_operand:HI 0 "register_operand" "=A")
  1684.         (ashift:HI (match_operand:HI 1 "general_operand" "A")
  1685.                    (const_int 16)))]
  1686.   ""
  1687.   "%0=%1<<16"
  1688.   [(set_attr "type" "special")])
  1689.  
  1690.  
  1691.  
  1692. ;; Normal Arithmetic Shift Left
  1693.  
  1694.  
  1695. (define_expand "ashlhi3"
  1696.   [(set (match_operand:HI 0 "register_operand" "")
  1697.         (ashift:HI (match_operand:HI 1 "register_operand" "")
  1698.                    (match_operand:QI 2 "nonmemory_operand" "")))]
  1699.   ""
  1700.   "
  1701. {
  1702.   if (!TARGET_BMU)
  1703.   {
  1704.       /* If we are shifting by a constant we can do it in 1 or more
  1705.      1600 core shift instructions. The core instructions can
  1706.      shift by 1, 4, 8, or 16. */
  1707.       
  1708.       if (GET_CODE(operands[2]) == CONST_INT)
  1709.     ;
  1710.       else
  1711.       {
  1712.     rtx label1 = gen_label_rtx ();
  1713.     rtx label2 = gen_label_rtx ();
  1714. #if 0
  1715.     if (!dsp16xx_ashlhi3_libcall)
  1716.       dsp16xx_ashlhi3_libcall = gen_rtx (SYMBOL_REF, Pmode, ASHLHI3_LIBCALL);
  1717.  
  1718.       emit_library_call (dsp16xx_ashlhi3_libcall, 1, HImode, 2,
  1719.                  operands[1], HImode,
  1720.                  operands[2], QImode);
  1721.       emit_move_insn (operands[0], hard_libcall_value(HImode));
  1722.       DONE;
  1723. #else
  1724.     do_pending_stack_adjust ();
  1725.     emit_insn (gen_tstqi (operands[2]));
  1726.     emit_jump_insn (gen_bne (label1));
  1727.     emit_move_insn (operands[0], operands[1]);
  1728.     emit_jump_insn (gen_jump (label2));
  1729.     emit_barrier ();
  1730.     emit_label (label1);
  1731.  
  1732.     if (GET_CODE(operands[2]) != MEM)
  1733.       {
  1734.         rtx stack_slot;
  1735.         
  1736.         stack_slot = assign_stack_temp (QImode, GET_MODE_SIZE(QImode), 0);
  1737.         stack_slot = change_address (stack_slot, VOIDmode, XEXP (stack_slot, 0));
  1738.         emit_move_insn (stack_slot, operands[2]);
  1739.         operands[2] = stack_slot;
  1740.       }
  1741.     emit_insn (gen_match_ashlhi3_nobmu (operands[0], operands[1], operands[2]));
  1742.     emit_label (label2);
  1743.     DONE;
  1744. #endif
  1745.       }
  1746.   }
  1747. }")
  1748.  
  1749. (define_insn "match_ashlhi3"
  1750.   [(set (match_operand:HI 0 "register_operand" "=A,A,A")
  1751.         (ashift:HI (match_operand:HI 1 "register_operand" "A,A,A")
  1752.                    (match_operand:QI 2 "nonmemory_operand" "B,I,!h")))]
  1753.   "TARGET_BMU"
  1754.   "@
  1755.    %0=%1<<%2\;move %u0=%u0
  1756.    %0=%1<<%H2\;move %u0=%u0
  1757.    %0=%1<<%2\;move %u0=%u0"
  1758.   [(set_attr "type" "shift,shift_i,shift")])
  1759.  
  1760. (define_insn "match_ashlhi3_nobmu"
  1761.   [(set (match_operand:HI 0 "register_operand" "=A,A")
  1762.         (ashift:HI (match_operand:HI 1 "register_operand" "A,0")
  1763.            (match_operand:QI 2 "general_operand" "n,m")))]
  1764.   "!TARGET_BMU"
  1765.   "*
  1766. {
  1767.   if (which_alternative == 0)
  1768.     {
  1769.       emit_1600_core_shift (ASHIFT, operands, INTVAL(operands[2]));
  1770.       return \"\";
  1771.     }
  1772.   else
  1773.     {
  1774.       output_asm_insn (\"cloop=%2\", operands);
  1775.       output_asm_insn (\"do 0 \{\", operands);
  1776.       output_asm_insn (\"%0=%0<<1\", operands);
  1777.       return \"\}\";
  1778.     }
  1779. }")
  1780.  
  1781.  
  1782.  
  1783. ;;
  1784. ;; Jump Instructions
  1785. ;;
  1786.  
  1787. (define_expand "beq"
  1788.   [(set (pc)
  1789.     (if_then_else (eq (match_dup 1)
  1790.                       (const_int 0))
  1791.               (label_ref (match_operand 0 "" ""))
  1792.               (pc)))]
  1793.   ""
  1794.   "
  1795.    if (dsp16xx_compare_gen == gen_compare_reg)
  1796.      operands[1] = (*dsp16xx_compare_gen)(EQ, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1797.    else
  1798.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1799. }")
  1800.  
  1801. (define_expand "bne"
  1802.   [(set (pc)
  1803.     (if_then_else (ne (match_dup 1)
  1804.               (const_int 0))
  1805.               (label_ref (match_operand 0 "" ""))
  1806.               (pc)))]
  1807.   ""
  1808.   "
  1809.    if (dsp16xx_compare_gen == gen_compare_reg)
  1810.      operands[1] = (*dsp16xx_compare_gen)(NE, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1811.    else
  1812.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1813. }")
  1814.  
  1815.  
  1816. (define_expand "bgt"
  1817.   [(set (pc)
  1818.     (if_then_else (gt (match_dup 1)
  1819.                       (const_int 0))
  1820.               (label_ref (match_operand 0 "" ""))
  1821.               (pc)))]
  1822.   ""
  1823.   "
  1824.    if (dsp16xx_compare_gen == gen_compare_reg)
  1825.      operands[1] = (*dsp16xx_compare_gen)(GT, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1826.    else
  1827.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1828. }")
  1829.  
  1830.  
  1831. (define_expand "bge"
  1832.   [(set (pc)
  1833.     (if_then_else (ge (match_dup 1)
  1834.                       (const_int 0))
  1835.               (label_ref (match_operand 0 "" ""))
  1836.               (pc)))]
  1837.   ""
  1838.   "
  1839.    if (dsp16xx_compare_gen == gen_compare_reg)
  1840.      operands[1] = (*dsp16xx_compare_gen)(GE, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1841.    else
  1842.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1843. }")
  1844.  
  1845.  
  1846. (define_expand "blt"
  1847.   [(set (pc)
  1848.     (if_then_else (lt (match_dup 1)
  1849.                       (const_int 0))
  1850.               (label_ref (match_operand 0 "" ""))
  1851.               (pc)))]
  1852.   ""
  1853.   "
  1854.    if (dsp16xx_compare_gen == gen_compare_reg)
  1855.      operands[1] = (*dsp16xx_compare_gen)(LT, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1856.    else
  1857.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1858. }")
  1859.  
  1860.  
  1861. (define_expand "ble"
  1862.   [(set (pc)
  1863.     (if_then_else (le (match_dup 1)
  1864.                       (const_int 0))
  1865.               (label_ref (match_operand 0 "" ""))
  1866.               (pc)))]
  1867.   ""
  1868.   "
  1869.    if (dsp16xx_compare_gen == gen_compare_reg)
  1870.      operands[1] = (*dsp16xx_compare_gen)(LE, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1871.    else
  1872.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1873. }")
  1874.  
  1875.  
  1876. (define_expand "bgtu"
  1877.   [(set (pc)
  1878.     (if_then_else (gtu (match_dup 1)
  1879.                        (const_int 0))
  1880.               (label_ref (match_operand 0 "" ""))
  1881.               (pc)))]
  1882.   ""
  1883.   "
  1884.    if (dsp16xx_compare_gen == gen_compare_reg)
  1885.      operands[1] = (*dsp16xx_compare_gen)(GTU, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1886.    else
  1887.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1888. }")
  1889.  
  1890.  
  1891. (define_expand "bgeu"
  1892.   [(set (pc)
  1893.     (if_then_else (geu (match_dup 1)
  1894.                        (const_int 0))
  1895.               (label_ref (match_operand 0 "" ""))
  1896.               (pc)))]
  1897.   ""
  1898.   "
  1899.    if (dsp16xx_compare_gen == gen_compare_reg)
  1900.      operands[1] = (*dsp16xx_compare_gen)(GEU, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1901.    else
  1902.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1903. }")
  1904.  
  1905.  
  1906. (define_expand "bltu"
  1907.   [(set (pc)
  1908.     (if_then_else (ltu (match_dup 1)
  1909.                        (const_int 0))
  1910.               (label_ref (match_operand 0 "" ""))
  1911.               (pc)))]
  1912.   ""
  1913.   "
  1914.    if (dsp16xx_compare_gen == gen_compare_reg)
  1915.      operands[1] = (*dsp16xx_compare_gen)(LTU, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1916.    else
  1917.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1918. }")
  1919.  
  1920.  
  1921. (define_expand "bleu"
  1922.   [(set (pc)
  1923.     (if_then_else (leu (match_dup 1)
  1924.                        (const_int 0))
  1925.               (label_ref (match_operand 0 "" ""))
  1926.               (pc)))]
  1927.   ""
  1928.   "
  1929.    if (dsp16xx_compare_gen == gen_compare_reg)
  1930.      operands[1] = (*dsp16xx_compare_gen)(LEU, dsp16xx_compare_op0, dsp16xx_compare_op1);
  1931.    else
  1932.      operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
  1933. }")
  1934.  
  1935.  
  1936. (define_insn ""
  1937.   [(set (pc)
  1938.     (if_then_else (match_operator 1 "comparison_operator" 
  1939.                                       [(cc0) (const_int 0)])
  1940.               (label_ref (match_operand 0 "" ""))
  1941.               (pc)))]
  1942.   "!TARGET_NEAR_JUMP"
  1943.   "pt=%l0\;if %C1 goto pt"
  1944.   [(set_attr "type" "cond_jump")])
  1945.  
  1946. (define_insn ""
  1947.   [(set (pc)
  1948.     (if_then_else (match_operator 1 "comparison_operator" 
  1949.                                       [(cc0) (const_int 0)])
  1950.               (label_ref (match_operand 0 "" ""))
  1951.               (pc)))]
  1952.   "TARGET_NEAR_JUMP"
  1953.   "if %C1 goto %l0"
  1954.   [(set_attr "type" "cond_jump")])
  1955.  
  1956. ;;
  1957. ;; Negated conditional jump instructions.
  1958. ;; These are necessary because jump optimization can turn
  1959. ;; direct-conditional branches into reverse-conditional
  1960. ;; branches.
  1961.  
  1962. (define_insn ""
  1963.   [(set (pc)
  1964.     (if_then_else (match_operator 1 "comparison_operator" 
  1965.                                       [(cc0) (const_int 0)])
  1966.                   (pc)
  1967.               (label_ref (match_operand 0 "" ""))))]
  1968.   "!TARGET_NEAR_JUMP"
  1969.   "pt=%l0\;if %I1 goto pt"
  1970.   [(set_attr "type" "cond_jump")])
  1971.  
  1972. (define_insn ""
  1973.   [(set (pc)
  1974.     (if_then_else (match_operator 1 "comparison_operator" 
  1975.                                       [(cc0) (const_int 0)])
  1976.                   (pc)
  1977.               (label_ref (match_operand 0 "" ""))))]
  1978.   "TARGET_NEAR_JUMP"
  1979.   "if %I1 goto %l0"
  1980.   [(set_attr "type" "cond_jump")])
  1981.  
  1982.  
  1983. ;;
  1984. ;; JUMPS
  1985. ;;
  1986.  
  1987. (define_insn "jump"
  1988.   [(set (pc)
  1989.         (label_ref (match_operand 0 "" "")))]
  1990.   ""
  1991.   "*
  1992.    {
  1993.     if (TARGET_NEAR_JUMP)
  1994.         return \"goto %l0\";
  1995.         else
  1996.         return \"pt=%l0\;goto pt\";
  1997.    }"
  1998.    [(set_attr "type" "jump")])
  1999.  
  2000.  
  2001. (define_insn "indirect_jump"
  2002.   [(set (pc) (match_operand:QI 0 "register_operand" "A"))]
  2003.   ""
  2004.   "pt=%0\;goto pt"
  2005.    [(set_attr "type" "jump")])
  2006.  
  2007. (define_insn "tablejump"
  2008.   [(set (pc) (match_operand:QI 0 "register_operand" "A"))
  2009.    (use (label_ref (match_operand 1 "" "")))]
  2010.   ""
  2011.   "pt=%0\;goto pt"
  2012.    [(set_attr "type" "jump")])
  2013.  
  2014. ;;
  2015. ;; FUNCTION CALLS
  2016. ;;
  2017.  
  2018. ;; Call subroutine with no return value.
  2019.  
  2020.  
  2021. (define_expand "call"
  2022.   [(parallel [(call (match_operand:QI 0 "" "")
  2023.                 (match_operand 1 "" ""))
  2024.          (clobber (reg:QI 24))])]
  2025.   ""
  2026.   "
  2027. {
  2028.   if (GET_CODE (operands[0]) == MEM
  2029.       && ! call_address_operand (XEXP (operands[0], 0), QImode))
  2030.     operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
  2031.                force_reg (Pmode, XEXP (operands[0], 0)));
  2032. }")
  2033.  
  2034. (define_insn ""
  2035.   [(parallel [(call (mem:QI (match_operand:QI 0 "call_address_operand" "hR"))
  2036.                         (match_operand 1 "" ""))
  2037.           (clobber (reg:QI 24))])]
  2038.   ""
  2039.   "*
  2040. {
  2041.     if (GET_CODE (operands[0]) == REG || 
  2042.     (GET_CODE(operands[0]) == SYMBOL_REF && !TARGET_NEAR_CALL))
  2043.     return \"pt=%0\;call pt\";
  2044.     else
  2045.         return \"call %0\";
  2046. }"
  2047. [(set_attr "type" "call")])
  2048.  
  2049. ;; Call subroutine with return value.
  2050.  
  2051. (define_expand "call_value"
  2052.   [(parallel [(set (match_operand 0 "register_operand" "=f")
  2053.           (call (match_operand:QI 1 "call_address_operand" "hR")
  2054.                     (match_operand:QI 2 "" "")))
  2055.           (clobber (reg:QI 24))])]
  2056.   ""
  2057.   "
  2058. {
  2059.   if (GET_CODE (operands[1]) == MEM
  2060.       && ! call_address_operand (XEXP (operands[1], 0), QImode))
  2061.     operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
  2062.                force_reg (Pmode, XEXP (operands[1], 0)));
  2063. }")
  2064.  
  2065. (define_insn ""
  2066.   [(parallel [(set (match_operand 0 "register_operand" "=f")
  2067.           (call (mem:QI (match_operand:QI 1 "call_address_operand" "hR"))
  2068.                             (match_operand:QI 2 "" "")))
  2069.           (clobber (reg:QI 24))])]
  2070.   ""
  2071.   "*
  2072. {
  2073.     if (GET_CODE (operands[1]) == REG ||
  2074.     (GET_CODE(operands[1]) == SYMBOL_REF && !TARGET_NEAR_CALL))
  2075.     return \"pt=%1\;call pt\";
  2076.     else
  2077.         return \"call %1\";
  2078. }"
  2079. [(set_attr "type" "call")])
  2080.  
  2081.  
  2082. (define_expand "untyped_call"
  2083.   [(parallel [(call (match_operand 0 "" "")
  2084.             (const_int 0))
  2085.           (match_operand 1 "" "")
  2086.           (match_operand 2 "" "")])]
  2087.   ""
  2088.   "
  2089. {
  2090.   int i;
  2091.  
  2092.   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
  2093.  
  2094.   for (i = 0; i < XVECLEN (operands[2], 0); i++)
  2095.     {
  2096.       rtx set = XVECEXP (operands[2], 0, i);
  2097.       emit_move_insn (SET_DEST (set), SET_SRC (set));
  2098.     }
  2099.  
  2100.   /* The optimizer does not know that the call sets the function value
  2101.      registers we stored in the result block.  We avoid problems by
  2102.      claiming that all hard registers are used and clobbered at this
  2103.      point.  */
  2104.   emit_insn (gen_blockage ());
  2105.  
  2106.   DONE;
  2107. }")
  2108.  
  2109. ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
  2110. ;; all of memory.  This blocks insns from being moved across this point.
  2111.  
  2112. (define_insn "blockage"
  2113.   [(unspec_volatile [(const_int 0)] 0)]
  2114.   ""
  2115.   "")
  2116.  
  2117. (define_insn "nop"
  2118.   [(const_int 0)]
  2119.   ""
  2120.   "nop"
  2121.   [(set_attr "type"     "nop")])
  2122.  
  2123. ;;
  2124. ;; PEEPHOLE PATTERNS
  2125. ;;
  2126.  
  2127.  
  2128. (define_peephole
  2129.   [(set (match_operand:QI 0 "register_operand" "=A")
  2130.         (reg:QI 16))
  2131.    (call (mem:QI (match_dup 0))
  2132.      (match_operand 1 "" "i"))]
  2133.    ""
  2134.    "call pt")
  2135.  
  2136.  
  2137. (define_peephole
  2138.   [(set (match_operand:QI 0 "register_operand" "=A")
  2139.         (reg:QI 16))
  2140.    (set (match_operand 1 "" "")
  2141.         (call (mem:QI (match_dup 0))
  2142.           (match_operand 2 "" "i")))]
  2143.    ""
  2144.    "call pt")
  2145.  
  2146. (define_peephole
  2147.   [(set (match_operand:HI 0 "register_operand" "=A")
  2148.     (ashift:HI (match_operand:HI 1 "register_operand" "A")
  2149.            (const_int 16)))
  2150.    (set (match_operand:HI 2 "register_operand" "")
  2151.     (match_dup 0))
  2152.    (set (match_dup 0)
  2153.     (ashiftrt:HI (match_dup 0) (const_int 16)))
  2154.    (set (match_dup 2)
  2155.     (match_dup 0))]
  2156.   ""
  2157.   "%0=%1<<16\;%0=%0>>16\;%u2=%u0\;%w2=%w0")
  2158.  
  2159. (define_peephole
  2160.   [(set (match_operand:HI 0 "register_operand" "=A")
  2161.     (ashift:HI (match_operand:HI 1 "register_operand" "A")
  2162.            (const_int 16)))
  2163.    (set (match_operand:HI 2 "register_operand" "")
  2164.     (match_dup 0))
  2165.    (set (match_dup 0)
  2166.     (lshiftrt:HI (match_dup 0) (const_int 16)))
  2167.    (set (match_dup 2)
  2168.     (match_dup 0))]
  2169.   ""
  2170.   "%0=%1<<16\;%0=%0>>16\;%0=%b0&0x0000\;%u2=%u0\;%w2=%w0")
  2171.